module encrypt(
    input clk,
    input rst,
    input [127:0]key,
    input [127:0]nonce,
    input [127:0]ad,
    input [127:0]plain,
    output [127:0]cipher,
    output [127:0]tag
    );

reg ascon_rst;
reg [4:0]ascon_rnd;
reg [319:0]ascon_Sin;
wire [319:0]ascon_Sout;
wire ascon_done;

Ascon_p ascon(
    .clk(clk),
    .rst(ascon_rst),
    .rnd(ascon_rnd),
    .Sin(ascon_Sin),
    .Sout(ascon_Sout),
    .done(ascon_done)
    );
wire [319:0]initial_S;
reg [4:0]now;
reg [4:0]next;
parameter [63:0]iv=64'h00001000808c0001;

assign initial_S={iv,key,nonce};
assign cipher=ascon_Sout[127:0];
assign tag=ascon_Sout[319:192]^key;

always@(posedge clk or negedge rst)
begin
    if(!rst)
        now<=0;
    else
        now<=next;
end

always@(*)
begin
    if(!rst)
    begin
        next=0;
    end
    else
        case(now)
            0:
                if(ascon_done)
                    next=1;
                else
                    next=0;
            2:
                if(ascon_done)
                    next=1;
                else
                    next=0;
            4:
                if(ascon_done)
                    next=1;
                else
                    next=0;
            6:
                if(ascon_done)
                    next=1;
                else
                    next=0;
            default:
                next=now+1;
        endcase
end

always@(posedge clk or negedge rst)
begin
    if(!rst)
    begin
        ascon_rst<=0;
    end
    else
        case(now)
            0:
            begin
                ascon_rst<=1;
                ascon_Sin<=initial_S;
                ascon_rnd<=12;
            end
            1:
            begin
                ascon_rst<=0;
                ascon_rst<=ascon_Sout;
            end
            2:
            begin
                ascon_rst<=1;
                ascon_Sin<=ascon_Sin^{192'b0,key}^{192'b0,ad};
                ascon_rnd<=8;
            end
            3:
            begin
                ascon_rst<=0;
                ascon_Sin<=ascon_Sout^{319'b0,1'b1};
            end
            4:
            begin
                ascon_rst<=1;
                ascon_Sin<=ascon_Sin^{192'b0,plain};
                ascon_rnd<=8;
            end
            5:
            begin
                ascon_rst<=0;
                ascon_rst<=ascon_Sout;
            end
            6:
            begin
                ascon_rst<=1;
                ascon_Sin<=ascon_Sin^{128'b0,key,64'b0};
            end
            7:
            begin
                ascon_rst<=0;
            end
            
        endcase
end

endmodule
